package com.drawquest.test;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ReflectionUtils {

    public static void planeCopy(Object source, Object dest) {
        List<Field> fields = getAllFields(new ArrayList<Field>(), source.getClass());
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                field.set(dest, field.get(source));

            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    public static List<Field> getAllFields(Class clazz) {
        return getAllFields(new ArrayList<Field>(), clazz);
    }

    private static List<Field> getAllFields(List<Field> fields, Class<?> type) {
        for (Field field : type.getDeclaredFields()) {
            if (!Modifier.isFinal(field.getModifiers())) {
                fields.add(field);
            }
        }

        if (type.getSuperclass() != null) {
            fields = getAllFields(fields, type.getSuperclass());
        }

        return fields;
    }

    public static void randomizeBasicFieldsValues(Object obj) {
        List<Field> allFields = new ArrayList<Field>();
        getAllFields(allFields, obj.getClass());
        for (Field f : allFields) {
            try {
                f.setAccessible(true);
                Class clazz = f.getType();
                Object value = f.get(obj);
                if (clazz == int.class || clazz == Integer.class) {
                    value = createRandomIntValue();
                }
                if (clazz == double.class || clazz == Double.class) {
                    value = createRandomDoubleValue();
                }
                if (clazz == float.class || clazz == Float.class) {
                    value = createRandomFloatValue();
                }
                if (clazz == boolean.class || clazz == Boolean.class) {
                    value = createRandomBooleanValue();
                }
                if (clazz == String.class) {
                    value = createRandomStringValue();
                }
                if (clazz == Date.class) {
                    value = createRandomDateValue();
                }
                if (clazz == java.sql.Date.class) {
                    value = createRandomSqlDateValue();
                }
                if (clazz == java.sql.Timestamp.class) {
                    value = createRandomTimestampValue();
                }
                f.set(obj, value);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    private static Date createRandomDateValue() {
        return new Date(createRandomIntValue());
    }

    private static Date createRandomTimestampValue() {
        return new Timestamp(createRandomIntValue());
    }

    private static java.sql.Date createRandomSqlDateValue() {
        return new java.sql.Date(createRandomIntValue());
    }

    private static Integer createRandomIntValue() {
        return (int) (Math.random() * 99999999);
    }

    private static Double createRandomDoubleValue() {
        return Math.random() * 999999999;
    }

    private static float createRandomFloatValue() {
        return (float) (Math.random() * 999999999);
    }

    private static boolean createRandomBooleanValue() {
        return Math.random() < 0.5;
    }

    private static String createRandomStringValue() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 50; i++) {
            sb.append(('a' + (int) (Math.random() * 20)));
        }
        return sb.toString();
    }
}
